<?php

require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'http_request_helper.class.php';
require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'http_message.class.php';

class HTTPClient
{
    private $cookies = array();
    private $response;
    private $lastURL;

    private $addHeaders = array();

    function __construct($params = array())
    {
        $paramNames = array_keys($params);

        $paramNames = array_map('strtolower', $paramNames);
        $params = array_combine($paramNames, $params);


        if (isset($params['user-agent'])) {
            $this->addHeaders[] = 'User-Agent: '.preg_replace('/[\x0-\x19]+/', ' ', $params['user-agent']);
        }
        if (isset($params['accept'])) {
            $this->addHeaders[] = 'Accept: '.preg_replace('/[\x0-\x19]+/', ' ', $params['accept']);
        }
        if (isset($params['accept-language'])) {
            $this->addHeaders[] = 'Accept-Language: '.preg_replace('/[\x0-\x19]+/', ' ', $params['accept-language']);
        }
        if (isset($params['accept-encoding'])) {
            $this->addHeaders[] = 'Accept-Encoding: '.preg_replace('/[\x0-\x19]+/', ' ', $params['accept-encoding']);
        }
        if (isset($params['accept-charset'])) {
            $this->addHeaders[] = 'Accept-Charset: '.preg_replace('/[\x0-\x19]+/', ' ', $params['accept-charset']);
        }
        /**
         * Это наверное не надо…
         */
        if (isset($params['keep-alive'])) {
            $this->addHeaders[] = 'Keep-Alive: '.preg_replace('/[\x0-\x19]+/', ' ', $params['keep-alive']);
        }
        if (isset($params['connection'])) {
            $this->addHeaders[] = 'Connection: '.preg_replace('/[\x0-\x19]+/', ' ', $params['connection']);
        }
    }

    /**
     * Выполнение GET-запроса
     *
     * @param string $URL
     * @param [optional]array assoc $data
     * @param [optional]int $timeout
     * @return HTTPResponse
     */
    function get($URL, $data = array(), $timeout = 0)
    {
        $addHeaders = $this->getAddHeaders($URL);

        echo "\n", implode("\n", $addHeaders);

        $this->response = new HTTPResponse(HTTPRequestHelper::GET_RAW(
            $URL, $data, $timeout, $addHeaders
        ));
        $this->lastURL = $URL;
        $this->saveCookie();
        return $this->response;
    }

    /**
     * Выполнение POST-запроса
     *
     * @param string $URL
     * @param [optional]array assoc $data
     * @param [optional]int $timeout
     * @return HTTPResponse
     */
    function post($URL, $data = array(), $timeout = 0)
    {
        $addHeaders = $this->getAddHeaders($URL);

        print_r($addHeaders);
        $this->response = new HTTPResponse(HTTPRequestHelper::POST_RAW(
            $URL, $data, $timeout, $addHeaders
        ));
        $this->lastURL = $URL;
        $this->saveCookie();
        return $this->response;
    }

    protected function getAddHeaders($URL)
    {
        $addHeaders = $this->addHeaders;

        if ($this->lastURL) {
            $addHeaders[] = 'Referer: '.$this->lastURL;
        }

        $cookies = array();
        $c = $this->getCookies($URL);
        print_r($c);
        foreach ($c as $name => $value) {
            $cookies[] = rawurlencode($name).'='.rawurlencode($value);
        }
        $cookies = implode('; ', $cookies);
        if (strlen($cookies)) {
            $addHeaders[] = 'Cookie: '.$cookies;
        }

        return $addHeaders;
    }

    protected function saveCookie()
    {
        /**
         * @todo Validate “path” and “domain” parameters
         */

        foreach ($this->response->getHeaderValues('set-cookie') as $cookie) {
            $cookieData = explode(';', $cookie);
            $cookieData = array_map('trim', $cookieData);
            $cookie = array_shift($cookieData);
            $cookie = explode('=', $cookie);
            if (! isset($cookie[1])) {
                continue;
            }
            $cookie = array_map('trim', $cookie);
            $cookie = array_map('rawurldecode', $cookie);
            $cookie = array(
                'name' => $cookie[0],
                'value' => $cookie[1],
            );

            foreach ($cookieData as $param) {
                $param = explode('=', $param);
                $param = array_map('trim', $param);
                $param = array_map('rawurldecode', $param);
                if (isset($param[0])) {
                    $paramName = strtolower($param[0]);
                    $paramValue = strval(@$param[1]);
                    switch ($paramName) {

                    case 'expires':
                        $expiresInLocalTime = strtotime($paramValue);
                        if ($expiresInLocalTime > 0) {
                            $cookie['expires'] = $expiresInLocalTime;
                        }
                        break;

                    case 'path':
                        $cookie['path'] = $paramValue;
                        break;

                    case 'domain':
                        $cookie['domain'] = $paramValue;
                        break;
                    }
                }

            }

            $URL = parse_url($this->lastURL);
            $domain = $URL['host'];
            $path = $URL['path'];

            if (empty($cookie['path'])) {
                $cookie['path'] = '/';
            }

            if (empty($cookie['domain'])) {
                $cookie['domain'] = $domain;
            }

            $this->cookies[] = $cookie;
        }
    }

    protected function getCookies($URL)
    {
        /**
         * @todo Выяснить маханизм пространства имён куки: доман?, путь?
         */


        $URL = parse_url($URL);

        $domain = $URL['host'];
        $path = $URL['path'];

        $cookiesToSend = array();

        foreach ($this->cookies as $key => $cookie) {
            if (isset($cookie['expires']) && (now() >= $cookie['expires'])) {
                unset($this->cookies[$key]);
            }
            //if (strpos(strrev($cookie['domain']), strrev($domain)) === 0) {
              //  if (strpos($cookie['path'], $path) === 0) {
                    $cookiesToSend[$cookie['name']] = $cookie['value'];
               // }
           // }
        }

        return $cookiesToSend;
    }

}

?>